package de.gwtprime.client.login;

import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.google.web.bindery.requestfactory.shared.Request;

import de.gwtprime.client.ClientFactory;
import de.gwtprime.client.PrimeRequestFactory;
import de.gwtprime.client.event.AuthenticationEvent;
import de.gwtprime.client.event.AuthenticationEvent.AuthenticationEventType;
import de.gwtprime.client.event.UserLoginAttemptEvent;
import de.gwtprime.client.event.handler.AuthenticationEventHandler;
import de.gwtprime.client.util.AppUtils;
import de.gwtprime.shared.requestFactory.User2Proxy;
import de.gwtprime.shared.requestFactory.request.User2Request;


/**
 * Manages the login/logout events and displays the corresponding uis
 * @author jan
 *
 */
public class AuthenticationManager extends Composite {

	private LoginContainer loginContainer = new LoginContainer();
	private LogoutContainer logoutContainer;

	/**
	 * The client factory
	 */
	private ClientFactory clientFactory;

	public AuthenticationManager(ClientFactory clientFactory) {

		this.clientFactory = clientFactory;
		
		logoutContainer = new LogoutContainer(clientFactory);
		RootPanel.get("loginBox").add(loginContainer);
		RootPanel.get("logoutBox").add(logoutContainer);
		loginContainer.setVisible(false);
		logoutContainer.setVisible(false);

		//changeUiToLoggedOut2();
		checkAuthenticationAndCreateUI();

		addAuthenticatonEventHandler();

	}



	/**
	 * Used to react to login/logout events and to switch the UI
	 */
	private void addAuthenticatonEventHandler() {
		clientFactory.getEventBus().addHandler(AuthenticationEvent.TYPE, new AuthenticationEventHandler() {

			@Override
			public void onAuthenticationChange(AuthenticationEvent event) {

				if(event.getType() == AuthenticationEventType.LOGIN){
					//changeUiToLoggedIn(event.getUser());
				}else if(event.getType() == AuthenticationEventType.LOGOUT){
					changeUiToLoggedOut2();
				}

			}
		});
	}

	/**
	 * Check if the user is logged in and show the corresponding UI for 
	 * his authentication state
	 */
	private void checkAuthenticationAndCreateUI() {

		final PrimeRequestFactory requestFactory = clientFactory.getRequestFactory();
		User2Request request = requestFactory.userRequest();

		Request<User2Proxy> r = request.findUserInSession();

		r.fire(new Receiver<User2Proxy>() {

			@Override
			public void onSuccess(User2Proxy resultUser) {
				if(resultUser==null){
					clientFactory.getEventBus().fireEvent(new UserLoginAttemptEvent(null));
					changeUiToLoggedOut2();
					return;
				}
				
				AppUtils.log("Logged in with user: "+resultUser != null ? resultUser.getEmail()+", id: "+resultUser.getId() : "-" );
				changeUiToLoggedIn(resultUser);
				clientFactory.setUser(resultUser);
				clientFactory.getEventBus().fireEvent(new UserLoginAttemptEvent(resultUser));
			}
		});
	}


	public void changeUiToLoggedIn(User2Proxy user){
		if(user!=null){

			changeUiToLoggedIn2(user);

			final PrimeRequestFactory requestFactory = clientFactory.getRequestFactory();
			User2Request request = requestFactory.userRequest();

			Request<User2Proxy> request2 = request.findUserByEmail(user.getEmail());
			request2.fire(new Receiver<User2Proxy>() {

				@Override
				public void onSuccess(User2Proxy response) {

					clientFactory.setUser(response);
					clientFactory.getEventBus().fireEvent(new UserLoginAttemptEvent(response));
				}
			});
		}
		else{
			changeUiToLoggedOut2();
			clientFactory.getEventBus().fireEvent(new UserLoginAttemptEvent(null));
		}
	}

	public void changeUiToLoggedIn2(User2Proxy user){
		loginContainer.setVisible(false);
		logoutContainer.setVisible(user);
	}

	public void changeUiToLoggedOut2(){
		loginContainer.setVisible(true);
		logoutContainer.setVisible(false);
	}
}
